#!/usr/bin/perl
# 
# Exercise 11.6
# 
# Write a program that finds all PDB files under a given folder and runs a program 
# (such as stride, or the program you wrote in Exercise 11.5) that reports on the sec-
# ondary structure of each PDB file. Store the results in a DBM file keyed on the file-
# name.
#
# Answer to Exercise 11.6
#
# Notice that we've incorporated subroutines from previous exercises.

use strict;
use warnings;
use File::Find;

# Talk to the user
print "Finding the PDB files and running \"stride\" on them...";

# May need to change the program for your system
my $stride =  '/usr/local/bin/stride';

# Search the directory "pdb" for pdb files, saving their names in the @pdbfiles array
my @pdbfiles = ();
find ( \&pdbfiles, 'pdb' );

# A hash to store the stride output, keyed by the PDB filename
my %strideoutputs = ();

# Capture the output of stride as a scalar value in a hash.
# Notice the use of the backtick operator `` to run another program.
# 2>&1 causes the error output also to be saved
foreach my $pdbfile (@pdbfiles) {
	$strideoutputs{$pdbfile} = join('', `$stride $pdbfile 2>&1`);
}

print "\n";
	
#
# Interact with the user, asking for words and showing the names of PDB files containing them
#

while( my $query = lc getuserinput("Find the stride output for what PDB file?: ") ) {

	if(defined $strideoutputs{$query}) {
		print $strideoutputs{$query},"\n";
	}else{
		print "The stride output for PDB file \"$query\" is not in the database\n";
	}
}

exit;

################################################################################
# Subroutines
################################################################################
#
# getuserinput
#  - prompt the user for a one-line response
#    return null if response is an empty line, q, or quit
#    Otherwise, return answer (with leading and trailing whitespace removed)
#
sub getuserinput {
	my($prompt) = @_;

	print $prompt;
	my $ans = <STDIN>;
	chomp $ans;
	if($ans =~ /^\s*$/ or $ans =~ /^\s*q\s*$/i or $ans =~ /^\s*quit\s*$/i) {
		return '';
	}else{
		$ans =~ s/^\s*//;
		$ans =~ s/\s*$//;
		return $ans;
	}
}

# Find all files whose names begin with "pdb" and end with ".ent"
sub pdbfiles {
	# Ignore files that aren't ASCII text files or aren't readable
	-T and -r or return 0;

	 /^pdb.*\.ent$/ and push(@pdbfiles, "$File::Find::name");

	 return 0;
}

